package com.snail.poker.dao;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.snail.poker.web.PageContext;
import com.snail.poker.web.bean.PageBean;

/**
 * 操作数据与数据库之间的数据相互传输的基类<br />
 * 同时也包括了数据分页的实现。
 * 
 * @author Snail
 * 
 */
public abstract class BaseDao extends HibernateDaoSupport {
	/**
	 * 获取分页对象<br/>
	 * offset 和 pagesize 已由拦截器负责获取, 并放入PagerContext中
	 */
	public PageBean getPagination(String hql) {
		return getPagination(hql, null, PageContext.getOffset(), PageContext
				.getPageSize());
	}

	/**
	 * 获取分页对象<br/>
	 * offset 和 pagesize 已由拦截器负责获取, 并放入PageContext中
	 */
	public PageBean getPagination(String hql, Object parm) {
		return getPagination(hql, new Object[] { parm }, PageContext
				.getOffset(), PageContext.getPageSize());
	}

	/**
	 * 获取分页对象<br/>
	 * offset 和 pagesize 已由拦截器负责获取, 并放入PageContext中
	 */
	public PageBean getPagination(String hql, Object parm_0, Object parm_1) {
		return getPagination(hql, new Object[] { parm_0, parm_1 }, PageContext
				.getOffset(), PageContext.getPageSize());
	}

	public PageBean getPagination(String hql, Object[] parms) {
		return getPagination(hql, parms, PageContext.getOffset(), PageContext
				.getPageSize());
	}

	/**
	 * 获取分页结果
	 * 
	 * @param hql
	 *            查询语句
	 * @param parms
	 *            语句所需参数数组
	 * @param offset
	 *            分页起始位
	 * @param pagesize
	 *            分页长度
	 * @return 分页数据对象
	 */
	public PageBean getPagination(final String hql, final Object[] parms,
			final int offset, final int pagesize) {

		return super.getHibernateTemplate().execute(
				new HibernateCallback<PageBean>() {
					@Override
					public PageBean doInHibernate(Session session)
							throws HibernateException, SQLException {
						// 获得总记录数
						String countHql = getCountQuery(hql);
						Query query = session.createQuery(countHql);
						setParameters(query, parms);
						int total = ((Long) query.uniqueResult()).intValue();

						// 获得当前页数据
						query = session.createQuery(hql);
						setParameters(query, parms);
						query.setFirstResult(offset);
						query.setMaxResults(pagesize);
						List<?> datas = query.list();
						PageBean pb = new PageBean();
						pb.setTotal(total);
						pb.setDatas(datas);

						return pb;
					}
				});
	}

	/**
	 * 根据HQL语句，获得查找总记录数的HQL语句<br/>
	 * from Orgnization o where o.parent is null <br/>
	 * ----> select count(*) from Orgnization o where o.parent is null
	 * 
	 */
	public String getCountQuery(String hql) {
		int index = hql.indexOf("from");
		if (index != -1) {
			return "select distinct count(*) " + hql.substring(index);
		}
		throw new RuntimeException("无效的查询语句!");
	}

	/**
	 * 对hql中的每个参数赋值 <br />
	 * 参数与值的对应
	 * 
	 * @param query
	 *            query语句
	 * @param parms
	 *            参数
	 * @return
	 */
	private Query setParameters(Query query, Object[] parms) {
		if (parms != null && parms.length > 0) {
			for (int i = 0; i < parms.length; i++) {
				query.setParameter(i, parms[i]);
			}
		}
		return query;
	}
}